import CanvasUtils from '@/utils/CanvasUtils';
import { SpotI } from '@/utils/CanvasUtils/CanvasType';
import Paint from '@/paint/Paint';
import { VectorStyleI } from '@/paint/Setting';
import Point from '@/paint/utils/Point';
import Vector from '@/paint/utils/Vector';
import BaseElement from '@/paint/elements/BaseElement';

export interface VectorI {
	/** 渲染类型 */
	type: "none" | "hover" | "active" | "dotted";
	/** 向量 */
	Vector: Vector;
	/** 向量风格 */
	style: VectorStyleI;
	/** 禁止修改 */
	Disabled: boolean;
	/** 响应角度 */
	Range: number;
}

export default class VectorLineElement extends BaseElement {

	/** 向量接口 */
	public vector: VectorI;

	protected angleRange: number = 30;

	/** 渲染层级 */
	public get Z_Index(): number {
		const type = this.vector.type;
		if (type === "none") {
			return 0;
		} else if (type === "hover") {
			return 1;
		} else if (type === "active") {
			return 2;
		} else if (type === "dotted") {
			return 3;
		} else {
			return 0;
		}
	}

	/** 渲染类型 */
	public get Type(): VectorI["type"] {
		return this.vector.type;
	}

	public set Type(type: VectorI["type"]) {
		if (!this.vector.Disabled) {
			this.vector.type = type;
		}
	}

	/**
	 * 构造函数
	 * @param paint 画板元素
	 * @param vector 向量类
	 */
	public constructor(paint: Paint, vector: VectorI) {
		super(paint);
		this.vector = vector;
	}

	public Draw(canvas: CanvasUtils): void {
		const { Vector: { Start, End } } = this.vector;
		const {
			Color, LineWidth,
			HoverColor, HoverLineWidth,
			ActiveColor, ActiveLineWidth,
			DottedColor, DottedLineWidth,
		} = this.vector.style;
		const type = this.vector.type;
		canvas.Save();
		canvas.BeginPath();
		canvas.MoveTo(Start);
		canvas.LineTo(End);
		if (type === "none") {
			canvas.StrokeStyle = Color;
			canvas.LineWidth = LineWidth;
		} else if (type === "hover") {
			canvas.StrokeStyle = HoverColor;
			canvas.LineWidth = HoverLineWidth;
		} else if (type === "active") {
			canvas.StrokeStyle = ActiveColor;
			canvas.LineWidth = ActiveLineWidth;
		} else if (type === "dotted") {
			canvas.LineDash = [1, 8];
			canvas.StrokeStyle = DottedColor;
			canvas.LineWidth = DottedLineWidth;
		}
		canvas.LineCap = "round";
		canvas.Stroke();
		canvas.Restore();
	}

	public OnRange({ X, Y }: SpotI): boolean {
		const point = new Point(X, Y);
		const { Range, Vector } = this.vector;
		const { Start, End, Angle } = Vector;
		return point.GetAngle(Start).OnRangeMiddle(Angle.Angle, Range)
			&& point.GetAngle(End).OnRangeMiddle(Angle.RotateAngle(180).Angle, Range);
	}

}
